﻿#region Copyright

// // The contents of this file are subject to the Mozilla Public License
// // Version 1.1 (the "License"); you may not use this file except in compliance
// // with the License. You may obtain a copy of the License at
// //   
// // http://www.mozilla.org/MPL/
// //   
// // Software distributed under the License is distributed on an "AS IS"
// // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
// // License for the specific language governing rights and limitations under 
// // the License.
// //   
// // The Initial Developer of the Original Code is Robert Smyth.
// // Portions created by Robert Smyth are Copyright (C) 2008-2013.
// //   
// // All Rights Reserved.

#endregion

using System;


namespace NoeticTools.NWorkflow.ProgressMonitoring
{
    public class ProgressData : IProgressScopeService
    {
        private readonly IProgressScope _rootScope;
        private IProgressScope _currentScope;

        public ProgressData()
        {
            _rootScope = new RootProgressScope();
            _currentScope = _rootScope;
            AddSequentialChildScope();
        }

        public IDisposable Sequence
        {
            get
            {
                var childScope = AddSequentialChildScope();
                return childScope;
            }
        }

        public IDisposable AlternativeFlows
        {
            get
            {
                var childScope = new AlternateProgressScope(this, _currentScope);
                Add(childScope);
                return childScope;
            }
        }

        public double UpdateWeights(double startingWeight)
        {
            return _currentScope.UpdateWeights(startingWeight);
        }

        IProgressScope IProgressScopeService.CurrentScope
        {
            get { return _currentScope; }
        }

        public double TotalCompleted
        {
            get { return _currentScope.TotalCompleted; }
        }

        void IProgressScopeService.Leave(IProgressScope scope)
        {
            _currentScope = scope.Parent;
        }

        private SequentialProgressScope AddSequentialChildScope()
        {
            var childScope = new SequentialProgressScope(this, _currentScope);
            Add(childScope);
            return childScope;
        }

        private void Add(IProgressScope childScope)
        {
            _currentScope.Enter(childScope);
            _currentScope = childScope;
        }

        public void AddStep(IStepRules stepRules)
        {
            _currentScope.AddStep(stepRules);
        }
    }
}